package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.dto.UserDetail;
import com.leyou.auth.utils.UserContext;
import com.leyou.common.exception.LyException;
import com.leyou.item.clients.ItemClient;

import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderRequestDTO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.OrderDetailService;
import com.leyou.trade.service.OrderLogisticsService;
import com.leyou.trade.service.OrderService;
import com.leyou.user.clients.UserClient;

import com.leyou.user.dto.AddressDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {


    private final ItemClient itemClient;
    private final OrderDetailService orderDetailService;
    private final UserClient userClient;
    private final OrderLogisticsService orderLogisticsService;

    public OrderServiceImpl(ItemClient itemClient, OrderDetailService orderDetailService, UserClient userClient,
                            OrderLogisticsService orderLogisticsService
    ) {
        this.itemClient = itemClient;
        this.orderDetailService = orderDetailService;
        this.userClient = userClient;
        this.orderLogisticsService = orderLogisticsService;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(OrderRequestDTO orderRequestDTO) {

        UserDetail user = UserContext.getUser();

        //carts的key是sku的id，value是购买对应商品的数量
        Map<Long, Integer> carts = orderRequestDTO.getCarts();

        if (CollectionUtils.isEmpty(carts)) {
            throw new LyException(400, "所购买商品不能为空");
        }

        Set<Long> skuIds = carts.keySet();

        if (CollectionUtils.isEmpty(skuIds)) {
            throw new LyException(400, "所购买商品Id不能为空");
        }


        Order order = new Order();

        order.setUserId(user.getId());
        order.setStatus(1);

        //根据sku的id集合查询，
        List<SkuDTO> skuDTOS = this.itemClient.listSkuByIds(new ArrayList<>(skuIds));

        if (CollectionUtils.isEmpty(skuDTOS)) {
            throw new LyException(500, "业务冲突");
        }

        //计算总价
        long total = 0;
        for (SkuDTO skuDTO : skuDTOS) {
            total += skuDTO.getPrice() * carts.get(skuDTO.getId());
        }


        //实际的金额应该是，sku的单价*num，并且多个sku的小计要累加
        order.setTotalFee(/*total*/1L);
        order.setActualFee(/*total*/1L);

        order.setPaymentType(orderRequestDTO.getPaymentType());
        order.setPostFee(0L);

        //保存订单并进行主键回显
        this.save(order);

        //处理订单详情，一个订单可能有多个详情，所以需要以提交的skuDTO集合转换为orderDetail=================================
        List<OrderDetail> orderDetails = skuDTOS.stream().map(skuDTO -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setImage(StringUtils.substringBefore(skuDTO.getImages(), ","));
            orderDetail.setSpec(skuDTO.getSpecialSpec());
            orderDetail.setPrice(skuDTO.getPrice());
            orderDetail.setTitle(skuDTO.getTitle());
            orderDetail.setNum(carts.get(skuDTO.getId()));
            orderDetail.setOrderId(order.getOrderId());
            orderDetail.setSkuId(skuDTO.getId());
            return orderDetail;
        }).collect(Collectors.toList());

        //批量保存spuDetail
        this.orderDetailService.saveBatch(orderDetails);

        //给物流表添加数据，
        Long addressId = orderRequestDTO.getAddressId();

        //后台获取地址，需要请求用户服务，或者地址服务，，trade请求user，携带参数，addressId,和userId

        //user服务接收请求，并根据userId和addressId共同查询地址信息，

        AddressDTO addressDTO = this.userClient.queryAddressById(addressId, user.getId());

        OrderLogistics orderLogistics = new OrderLogistics();

        BeanUtils.copyProperties(addressDTO,orderLogistics);

        orderLogistics.setOrderId(order.getOrderId());


        this.orderLogisticsService.save(orderLogistics);


       return order.getOrderId();

    }
}
